# Matrix.Configuration 测试运行脚本
# 用于运行所有测试项目并生成覆盖率报告

param(
    [Parameter(Mandatory=$false)]
    [string]$Configuration = "Debug",

    [Parameter(Mandatory=$false)]
    [switch]$Coverage,

    [Parameter(Mandatory=$false)]
    [switch]$Verbose,

    [Parameter(Mandatory=$false)]
    [switch]$CI
)

Write-Host "Matrix.Configuration 测试运行器" -ForegroundColor Green
Write-Host "========================" -ForegroundColor Green

# 获取脚本所在目录
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RootDir = Split-Path -Parent $ScriptDir

# 测试项目列表
$TestProjects = @(
    "$RootDir\tests\Matrix.Configuration.Domain.Tests\Matrix.Configuration.Domain.Tests.csproj",
    "$RootDir\tests\Matrix.Configuration.Application.Tests\Matrix.Configuration.Application.Tests.csproj",
    "$RootDir\tests\Matrix.Configuration.EntityFrameworkCore.Tests\Matrix.Configuration.EntityFrameworkCore.Tests.csproj"
)

# 检查项目是否存在
$ExistingProjects = @()
foreach ($project in $TestProjects) {
    if (Test-Path $project) {
        $ExistingProjects += $project
        Write-Host "找到测试项目: $(Split-Path -Leaf $project)" -ForegroundColor Cyan
    } else {
        Write-Warning "测试项目不存在: $project"
    }
}

if ($ExistingProjects.Count -eq 0) {
    Write-Error "没有找到任何测试项目"
    exit 1
}

# 构建所有测试项目
Write-Host "`n正在构建测试项目..." -ForegroundColor Yellow
foreach ($project in $ExistingProjects) {
    Write-Host "构建: $(Split-Path -Leaf $project)" -ForegroundColor Gray
    & dotnet build $project --configuration $Configuration --no-restore
    if ($LASTEXITCODE -ne 0) {
        Write-Error "构建失败: $(Split-Path -Leaf $project)"
        exit 1
    }
}

# 运行测试的函数
function Run-Tests {
    param(
        [string[]]$Projects,
        [string]$Config,
        [bool]$GenerateCoverage,
        [bool]$IsVerbose
    )

    $testResults = @()

    foreach ($project in $Projects) {
        $projectName = Split-Path -Leaf $project
        Write-Host "`n运行测试: $projectName" -ForegroundColor Yellow

        $arguments = @(
            "test",
            $project,
            "--configuration", $Config,
            "--no-build",
            "--logger", "console;verbosity=detailed"
        )

        if ($GenerateCoverage) {
            $arguments += @(
                "--collect:xunit",
                "--results-directory", "$RootDir\TestResults"
            )
        }

        if ($IsVerbose) {
            $arguments += "--verbosity", "normal"
        }

        # 设置测试结果输出目录
        $testResultsDir = "$RootDir\TestResults"
        if (!(Test-Path $testResultsDir)) {
            New-Item -ItemType Directory -Path $testResultsDir -Force | Out-Null
        }

        try {
            & dotnet @arguments
            $testResults += @{
                Project = $projectName
                Success = $LASTEXITCODE -eq 0
                ExitCode = $LASTEXITCODE
            }

            if ($LASTEXITCODE -ne 0) {
                Write-Warning "测试失败: $projectName (退出代码: $LASTEXITCODE)"
            } else {
                Write-Host "测试通过: $projectName" -ForegroundColor Green
            }
        }
        catch {
            Write-Error "运行测试时发生错误: $projectName"
            $testResults += @{
                Project = $projectName
                Success = $false
                ExitCode = -1
                Error = $_.Exception.Message
            }
        }
    }

    return $testResults
}

# 运行测试
Write-Host "`n开始运行测试..." -ForegroundColor Green
$testResults = Run-Tests -Projects $ExistingProjects -Config $Configuration -GenerateCoverage:$Coverage -IsVerbose:$Verbose

# 显示测试结果摘要
Write-Host "`n测试结果摘要" -ForegroundColor Green
Write-Host "============" -ForegroundColor Green

$totalTests = $testResults.Count
$passedTests = ($testResults | Where-Object { $_.Success }).Count
$failedTests = $totalTests - $passedTests

Write-Host "总测试项目: $totalTests" -ForegroundColor White
Write-Host "通过: $passedTests" -ForegroundColor Green
Write-Host "失败: $failedTests" -ForegroundColor $(if ($failedTests -gt 0) { "Red" } else { "Green" })

# 显示详细结果
if ($failedTests -gt 0) {
    Write-Host "`n失败的测试项目:" -ForegroundColor Red
    foreach ($result in $testResults | Where-Object { !$_.Success }) {
        Write-Host "- $($result.Project)" -ForegroundColor Red
        if ($result.ExitCode -ne 0) {
            Write-Host "  退出代码: $($result.ExitCode)" -ForegroundColor Gray
        }
        if ($result.Error) {
            Write-Host "  错误: $($result.Error)" -ForegroundColor Gray
        }
    }
}

# 生成覆盖率报告
if ($Coverage) {
    Write-Host "`n生成覆盖率报告..." -ForegroundColor Yellow

    try {
        # 如果安装了coverlet，可以生成HTML覆盖率报告
        $coverletCommand = "dotnet tool list --global | findstr coverlet"
        $hasCoverlet = & cmd /c $coverletCommand 2>$null

        if ($LASTEXITCODE -eq 0) {
            Write-Host "使用Coverlet生成覆盖率报告..." -ForegroundColor Gray

            foreach ($project in $ExistingProjects) {
                $projectName = Split-Path -Leaf $project
                $outputDir = "$RootDir\TestResults\$($projectName.Replace('.csproj', ''))\coverage"

                if (!(Test-Path $outputDir)) {
                    New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
                }

                & dotnet test $project `
                    --configuration $Configuration `
                    --collect:"XPlat Code Coverage" `
                    --results-directory $outputDir `
                    --diag:"$outputDir\coverage.diag"
            }

            Write-Host "覆盖率报告已生成到: $RootDir\TestResults" -ForegroundColor Green
        } else {
            Write-Warning "未安装Coverlet工具，跳过覆盖率报告生成"
            Write-Host "安装命令: dotnet tool install --global dotnet-coverage" -ForegroundColor Gray
        }
    }
    catch {
        Write-Warning "生成覆盖率报告时发生错误: $($_.Exception.Message)"
    }
}

# 退出码设置
if ($failedTests -gt 0) {
    Write-Host "`n有 $failedTests 个测试项目失败" -ForegroundColor Red
    if (-not $CI) {
        Write-Host "退出码: 1" -ForegroundColor Gray
    }
    exit 1
} else {
    Write-Host "`n所有测试通过！" -ForegroundColor Green
    Write-Host "退出码: 0" -ForegroundColor Gray
    exit 0
}